using System;
using System.Collections.Generic;
using System.Linq;
using Urs.Core;
using Urs.Core.Data;
using Urs.Data.Domain.Users;
using Urs.Data.Domain.Logging;
using Urs.Data;
using Urs.Data.Domain.Configuration;

namespace Urs.Services.Logging
{
    public partial class DatabaseLogger : ILogger
    {
        #region Fields

        private readonly IRepository<Log> _logRepository;
        private readonly IWebHelper _webHelper;
        private readonly IDbContext _dbContext;
        private readonly IDataProvider _dataProvider;
        private readonly CommonSettings _commonSettings;
        private readonly StoreInformationSettings _storeSettings;

        #endregion

        #region Ctor

        public DatabaseLogger(IRepository<Log> logRepository, IWebHelper webHelper,
            IDbContext dbContext, IDataProvider dataProvider, CommonSettings commonSettings, StoreInformationSettings storeInformationSettings)
        {
            this._logRepository = logRepository;
            this._webHelper = webHelper;
            this._dbContext = dbContext;
            this._dataProvider = dataProvider;
            this._commonSettings = commonSettings;
            this._storeSettings = storeInformationSettings;
        }

        #endregion

        #region Methods

        public virtual bool IsEnabled(LogLevel level)
        {
            switch (level)
            {
                case LogLevel.Debug:
                    return false;
                default:
                    return true;
            }
        }

        public virtual void DeleteLog(Log log)
        {
            if (log == null)
                throw new ArgumentNullException("log");

            _logRepository.Delete(log);
        }

        public virtual void ClearLog()
        {
            _dbContext.ExecuteSqlCommand("DELETE FROM LOG WHERE 1;");
        }

        public virtual IPagedList<Log> GetAllLogs(DateTime? fromUtc, DateTime? toUtc,
            string message, LogLevel? logLevel, int pageIndex, int pageSize)
        {
            var query = _logRepository.Table;
            if (fromUtc.HasValue)
                query = query.Where(l => fromUtc.Value <= l.CreateTime);
            if (toUtc.HasValue)
                query = query.Where(l => toUtc.Value >= l.CreateTime);
            if (logLevel.HasValue)
            {
                int logLevelId = (int)logLevel.Value;
                query = query.Where(l => l.LogLevelId == logLevelId);
            }
            if (!String.IsNullOrEmpty(message))
                query = query.Where(l => l.ShortMessage.Contains(message) || l.FullMessage.Contains(message));
            query = query.OrderByDescending(l => l.CreateTime);

            var log = new PagedList<Log>(query, pageIndex, pageSize);
            return log;
        }

        public virtual Log GetLogById(int logId)
        {
            if (logId == 0)
                return null;

            var log = _logRepository.GetById(logId);
            return log;
        }

        public virtual IList<Log> GetLogByIds(int[] logIds)
        {
            if (logIds == null || logIds.Length == 0)
                return new List<Log>();

            var query = from l in _logRepository.Table
                        where logIds.Contains(l.Id)
                        select l;
            var logItems = query.ToList();
            var sortedLogItems = new List<Log>();
            foreach (int id in logIds)
            {
                var log = logItems.Find(x => x.Id == id);
                if (log != null)
                    sortedLogItems.Add(log);
            }
            return sortedLogItems;
        }

        public virtual Log InsertLog(LogLevel logLevel, string shortMessage, string fullMessage = "", User user = null)
        {
            var ip = _webHelper.GetCurrentIpAddress();
            var pu = _webHelper.GetThisPageUrl(true);
            var referrer = _webHelper.GetUrlReferrer();
            var log = new Log()
            {
                LogLevel = logLevel,
                ShortMessage = shortMessage,
                FullMessage = fullMessage,
                IpAddress = ip,
                User = user,
                PageUrl = pu,
                ReferrerUrl = referrer,
                CreateTime = DateTime.Now
            };

            _logRepository.Insert(log);

            return log;
        }

        #endregion
    }
}
